﻿using System;
using System.Collections.Generic;
using System.Linq;
using CoreLibrary.Date;
using Entities.DataBase;
using Entities.DataBase.Obj;
using Entities.DataBase.Persistent;
using WebService.Service.Transfer;

namespace WebService.Service {

    public class ReportServiceX : AbstractService, IReportServiceX {

        public List<Statistic> GetStatistics(string passport, StatisticRequest request) {
            return Run(passport, token => {
                var currentMonth = request.CurrentMonth != null && (bool) request.CurrentMonth;
                var currentYear  = request.CurrentYear != null  && (bool) request.CurrentYear;

                var from = request.From == null ? DateUtil.Epoch.Date  : ((DateTime)request.From).Date;
                var to   = request.To   == null ? DateTime.UtcNow.Date : ((DateTime)request.To).Date;

                var purchaseRecords = GetPurchaseRecords(currentMonth, currentYear, from, to);
                var orderRecords    = GetOrderRecords(currentMonth, currentYear, from, to);
                var products        = Locate<IProductRepository>()
                                     .GetAll()
                                     .Where(p => string.IsNullOrEmpty(request.ProductId) || p.ProductId.Equals(request.ProductId))
                                     .OrderBy(p => p.ListOrder);

                return products.Select(p => {
                    var records = purchaseRecords.Where(r => r.ProductId.Equals(p.ProductId)).ToList();
                    var orders  = orderRecords.Where(o => o.ProductId.Equals(p.ProductId)).ToList();
                    return new Statistic {
                        ProductId              = p.ProductId,
                        ProductName            = p.CName,
                        PurchasePrice          = (double)records.Sum(r => r.Cost * r.Count),
                        Postage                = (double)records.Sum(r => r.Postage     * r.Count),
                        OrderPostage           = (double)orders.Sum(o => o.AvgOrderPostage * o.Count),
                        OrderPrice             = (double)orders.Sum(o => o.Price * o.Count),
                        TotalNumberOfPurchases = records.Sum(r => r.Count),
                        TotalNumberOfOrders    = orders.Sum(r => r.Count),
                    };
                }).ToList();
            });
        }

        private static IEnumerable<PurchaseRecordInfo> GetPurchaseRecords(bool currentMonth, bool currentYear, DateTime from, DateTime to) {
            var records = Locate<IPurchaseRecordRepository>().ListAllRecords();
            if (currentMonth) {
                return records.Where(r => r.DateCreated.Month == DateTime.UtcNow.Month).ToList();
            }
            return currentYear ? records.Where(r => r.DateCreated.Year == DateTime.UtcNow.Year).ToList() : records.Where(r => r.DateCreated.Date.CompareTo(@from) >= 0 && r.DateCreated.Date.CompareTo(to) <= 0).ToList();
        }

        private static IEnumerable<OrderRecord> GetOrderRecords(bool currentMonth, bool currentYear, DateTime from, DateTime to) {
            var orders = Locate<IOrderRecordRepository>().ListCompleteRecords();
            if (currentMonth) {
                return orders.Where(r => r.DateCreated.Month == DateTime.UtcNow.Month).ToList();
            }
            return currentYear ? orders.Where(r => r.DateCreated.Year == DateTime.UtcNow.Year).ToList() : orders.Where(r => r.DateCreated.Date.CompareTo(@from) >= 0 && r.DateCreated.Date.CompareTo(to) <= 0).ToList();
        }

    }
}
